package com.ruoyi.factorydata.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.factorydata.domain.PurchaseOrderDetail;
import com.ruoyi.factorydata.domain.PurchaseOrderInfo;
import com.ruoyi.factorydata.mapper.PurchaseOrderDetailMapper;
import com.ruoyi.factorydata.mapper.PurchaseOrderInfoMapper;
import com.ruoyi.factorydata.service.*;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysUserService;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

/**
 * 采购单信息Service业务层处理
 *
 * @author ruoyi
 * @date 2025-07-17
 */
@Service
public class PurchaseOrderInfoServiceImpl extends ServiceImpl<PurchaseOrderInfoMapper, PurchaseOrderInfo> implements IPurchaseOrderInfoService {
    private final PurchaseOrderInfoMapper purchaseOrderInfoMapper;

    private final PurchaseOrderDetailMapper purchaseOrderDetailMapper;

    private final ISysUserService sysUserService;

    private final IWarehouseInfoService warehouseInfoService;
    private final IMaterialUnitDataService materialUnitDataService;
    private final IInventoryReceiptInfoService inventoryReceiptInfoService;
    private final ISupplierDataService supplierDataService;
    private final ISysConfigService sysConfigService;

    @Lazy
    public PurchaseOrderInfoServiceImpl(PurchaseOrderInfoMapper purchaseOrderInfoMapper,
                                        PurchaseOrderDetailMapper purchaseOrderDetailMapper,
                                        ISysUserService sysUserService,
                                        IWarehouseInfoService warehouseInfoService,
                                        IMaterialUnitDataService materialUnitDataService,
                                        IInventoryReceiptInfoService inventoryReceiptInfoService,
                                        ISupplierDataService supplierDataService,
                                        ISysConfigService sysConfigService) {
        this.purchaseOrderInfoMapper = purchaseOrderInfoMapper;
        this.purchaseOrderDetailMapper = purchaseOrderDetailMapper;
        this.sysUserService = sysUserService;
        this.warehouseInfoService = warehouseInfoService;
        this.materialUnitDataService = materialUnitDataService;
        this.inventoryReceiptInfoService = inventoryReceiptInfoService;
        this.supplierDataService = supplierDataService;
        this.sysConfigService = sysConfigService;
    }

    /**
     * 查询采购单信息
     *
     * @param id 采购单信息主键
     * @return 采购单信息
     */
    @Override
    public PurchaseOrderInfo selectPurchaseOrderInfoById(Long id) {
        PurchaseOrderInfo purchaseOrderInfo = purchaseOrderInfoMapper.selectPurchaseOrderInfoById(id);
        PurchaseOrderDetail detailQuery = new PurchaseOrderDetail();
        detailQuery.setPurchaseOrderId(id);
        List<PurchaseOrderDetail> purchaseOrderDetails = purchaseOrderDetailMapper.selectPurchaseOrderDetailList(detailQuery);
        HashMap<Long, String> unitNameCache = new HashMap<>();
        purchaseOrderDetails.forEach(purchaseOrderDetail -> {
            String unitName = materialUnitDataService.getByIdAndCache(Long.valueOf(purchaseOrderDetail.getUnit()), unitNameCache);
            purchaseOrderDetail.setMaterialUnitName(unitName);
        });
        purchaseOrderInfo.setPurchaseOrderDetailList(purchaseOrderDetails);
        purchaseOrderInfo.setCreateByName(sysUserService.getUserNameByIdAndCache(Long.parseLong(purchaseOrderInfo.getCreateBy()), new HashMap<>()));
        return purchaseOrderInfo;
    }

    /**
     * 查询采购单信息列表
     *
     * @param purchaseOrderInfo 采购单信息
     * @return 采购单信息
     */
    @Override
    public List<PurchaseOrderInfo> selectPurchaseOrderInfoList(PurchaseOrderInfo purchaseOrderInfo) {
        List<PurchaseOrderInfo> purchaseOrderInfos = purchaseOrderInfoMapper.selectPurchaseOrderInfoList(purchaseOrderInfo);
        HashMap<Long, String> createByCache = new HashMap<>();
        HashMap<Long, String> supplierCache = new HashMap<>();
        HashMap<Long, String> warehouseCache = new HashMap<>();
        for (PurchaseOrderInfo purchaseOrder : purchaseOrderInfos) {
            String createByName = sysUserService.getUserNameByIdAndCache(Long.parseLong(purchaseOrder.getCreateBy()), createByCache);
            String warehouseName = warehouseInfoService.getNameByIdAndCache(purchaseOrder.getWarehouseId(), warehouseCache);
            String supplierName = supplierDataService.getSupplierNameByIdAndCache(purchaseOrder.getSupplierId(), supplierCache);
            Integer buyNum = purchaseOrderDetailMapper.getBuyNum(purchaseOrder.getId());
            purchaseOrder.setWarehouseName(warehouseName);
            purchaseOrder.setSupplierName(supplierName);
            purchaseOrder.setTotalNum(buyNum);
            purchaseOrder.setCreateByName(createByName);
        }
        return purchaseOrderInfos;
    }

    /**
     * 新增采购单信息
     *
     * @param purchaseOrderInfo 采购单信息
     * @return 结果
     */
    @Override
    @Transactional
    public int insertPurchaseOrderInfo(PurchaseOrderInfo purchaseOrderInfo) {
        Assert.isTrue(!CollectionUtils.isEmpty(purchaseOrderInfo.getPurchaseOrderDetailList()), "采购单明细不能为空");
        purchaseOrderInfo.setPurchaseOrderCode("PO" + System.currentTimeMillis());
        purchaseOrderInfo.setCreateTime(DateUtils.getNowDate());
        purchaseOrderInfo.setCreateBy(SecurityUtils.getLoginUser().getUserId() + "");
        String purchaseOrderIsAuth = sysConfigService.selectConfigByKey("purchaseOrderIsAuth");
        if(StringUtils.isNotBlank(purchaseOrderIsAuth)&&Integer.parseInt(purchaseOrderIsAuth)==0&&purchaseOrderInfo.getStatus()!=null&&purchaseOrderInfo.getStatus()==1){
            purchaseOrderInfo.setStatus(2L);
        }
        int save = purchaseOrderInfoMapper.insertPurchaseOrderInfo(purchaseOrderInfo);
        if (save > 0) {
            for (PurchaseOrderDetail purchaseOrderDetail : purchaseOrderInfo.getPurchaseOrderDetailList()) {
                purchaseOrderDetail.setPurchaseOrderId(purchaseOrderInfo.getId());
                purchaseOrderDetail.setPurchaseOrderCode(purchaseOrderInfo.getPurchaseOrderCode());
                purchaseOrderDetail.setCreateTime(DateUtils.getNowDate());
                purchaseOrderDetail.setCreateBy(SecurityUtils.getLoginUser().getUserId() + "");
                purchaseOrderDetailMapper.insertPurchaseOrderDetail(purchaseOrderDetail);
            }
        }
        if(purchaseOrderInfo.getStatus()!=null&&purchaseOrderInfo.getStatus()==2){
            //生成入库单信息
            boolean ret = inventoryReceiptInfoService.generateInventoryReceiptInfo(purchaseOrderInfo);
            Assert.isTrue(ret, "生成入库单信息失败");
        }
        return save;
    }

    /**
     * 修改采购单信息
     *
     * @param purchaseOrderInfo 采购单信息
     * @return 结果
     */
    @Override
    @Transactional
    public int updatePurchaseOrderInfo(PurchaseOrderInfo purchaseOrderInfo) {
        purchaseOrderInfo.setUpdateTime(DateUtils.getNowDate());

        String purchaseOrderIsAuth = sysConfigService.selectConfigByKey("purchaseOrderIsAuth");
        if(StringUtils.isNotBlank(purchaseOrderIsAuth)&&Integer.parseInt(purchaseOrderIsAuth)==0&&purchaseOrderInfo.getStatus()==1){
            purchaseOrderInfo.setStatus(2L);
        }
        int update = purchaseOrderInfoMapper.updatePurchaseOrderInfo(purchaseOrderInfo);
        if (update > 0) {
            purchaseOrderDetailMapper.removeByPurchaseOrderId(purchaseOrderInfo.getId());
            for (PurchaseOrderDetail purchaseOrderDetail : purchaseOrderInfo.getPurchaseOrderDetailList()) {
                purchaseOrderDetail.setPurchaseOrderId(purchaseOrderInfo.getId());
                purchaseOrderDetail.setPurchaseOrderCode(purchaseOrderInfo.getPurchaseOrderCode());
                purchaseOrderDetail.setCreateTime(DateUtils.getNowDate());
                purchaseOrderDetail.setCreateBy(SecurityUtils.getLoginUser().getUserId() + "");
                purchaseOrderDetailMapper.insertPurchaseOrderDetail(purchaseOrderDetail);
            }
        }

        if(purchaseOrderInfo.getStatus()==2){
            //生成入库单信息
            boolean ret = inventoryReceiptInfoService.generateInventoryReceiptInfo(purchaseOrderInfo);
            Assert.isTrue(ret, "生成入库单信息失败");
        }
        return update;
    }

    /**
     * 批量删除采购单信息
     *
     * @param ids 需要删除的采购单信息主键
     * @return 结果
     */
    @Override
    @Transactional
    public int deletePurchaseOrderInfoByIds(Long[] ids) {
        Assert.notNull(ids, "删除的采购单信息不能为空");
        List<Long> idList = Arrays.asList(ids);
        //是否存在审核中的采购单
        Integer count = lambdaQuery().eq(PurchaseOrderInfo::getStatus, 1)
                .in(PurchaseOrderInfo::getId, idList)
                .count();
        Assert.isTrue(count == 0, "存在审核中的采购单");
//        return purchaseOrderInfoMapper.deletePurchaseOrderInfoByIds(ids);
        boolean remove = removeByIds(idList);
        if (remove) {
            idList.forEach(purchaseOrderDetailMapper::removeByPurchaseOrderId);
        }
        return remove ? 1 : 0;
    }

    /**
     * 删除采购单信息信息
     *
     * @param id 采购单信息主键
     * @return 结果
     */
    @Override
    public int deletePurchaseOrderInfoById(Long id) {
        PurchaseOrderInfo purchaseOrderInfo = getById(id);
        Assert.isTrue(purchaseOrderInfo.getStatus() != 1, "存在审核中的采购单");
        return purchaseOrderInfoMapper.deletePurchaseOrderInfoById(id);
    }

    @Override
    @Transactional
    public int auth(PurchaseOrderInfo purchaseOrderInfo) {
        Assert.notNull(purchaseOrderInfo, "采购单信息不能为空");
        Assert.notNull(purchaseOrderInfo.getId(), "采购单信息不能为空");
        Assert.isTrue(purchaseOrderInfo.getStatus() == 2 || purchaseOrderInfo.getStatus() == -1, "采购单审核状态错误");
        PurchaseOrderInfo orderInfo = selectPurchaseOrderInfoById(purchaseOrderInfo.getId());
        Assert.notNull(orderInfo, "采购单信息不存在");
        Assert.isTrue(orderInfo.getStatus() == 1, "采购单审核状态错误");
        orderInfo.setStatus(purchaseOrderInfo.getStatus());
        orderInfo.setAuthContext(purchaseOrderInfo.getAuthContext());
        orderInfo.setUpdateTime(DateUtils.getNowDate());
        orderInfo.setUpdateBy(SecurityUtils.getLoginUser().getUserId() + "");
        int auth = purchaseOrderInfoMapper.updatePurchaseOrderInfo(orderInfo);
        if (auth > 0 && purchaseOrderInfo.getStatus() == 2) {
            //生成入库单信息
            boolean ret = inventoryReceiptInfoService.generateInventoryReceiptInfo(orderInfo);
            Assert.isTrue(ret, "生成入库单信息失败");
        }
        return auth;
    }
}